package k2_oop.p9_collection.demo02;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.stream.Collectors;

public class DecodeMagic_java {

    static Random random = new Random();

    public static final String[] PLAYINGCARDNUMBER =
            {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
    public static final String[] PLAYINGCARDFLOWER = {"红桃","黑桃","梅花","方片"};

    public static int CARDCOUNT = 8;

    public static final String SWAPTITLE = "见证奇迹的时刻";

    public static List<String> playingCard = new ArrayList<>();


    public static void decode(String name,String position,String gender){

        //初始化被藏起来的第一张牌
        String kingCard = "";

        //第一个步骤：随机抽取4张牌
        System.out.println("=====随机抽取的4张牌=====");
        int stopFlag = 0;
        //随机四张卡牌
        while(stopFlag<4){
            String currentCard = PLAYINGCARDFLOWER[random.nextInt(PLAYINGCARDFLOWER.length)]
                    + PLAYINGCARDNUMBER[random.nextInt(PLAYINGCARDNUMBER.length)];

            //判断当前列表中是否存在刚刚随机出来的卡牌，避免卡牌重复
            if (!playingCard.contains(currentCard)) {
                playingCard.add(currentCard);
                stopFlag++;
            }
        }
        System.out.println(playingCard);


        //第二个步骤：把4张牌对半撕开，堆在一起
        System.out.println("=====撕开后堆在一起的8张牌=====");

        //在原列表基础上添加 撕开之后的四张卡牌
        //撕开之后的卡牌也已列表形式存在，用addAll形式添加
        playingCard.addAll(
                //这里使用 java8 新特性实现
                playingCard.stream()
                        .map(card -> card + "+")
                        .collect(Collectors.toList())
        );
        System.out.println(playingCard);

        //第三个步骤：根据名字的字数往下放牌，每说一个字就把第一张牌放到最下面
        System.out.println("======你的名字是"+name+",长度是"+name.length()+
                "往下放"+name.length()+"牌后的8张牌====");
        playingCard = swapCard(name.length());
        System.out.println(playingCard);


        //第四个步骤：拿起最上面的三张牌并插到中间
        System.out.println("=====最上面的三张牌插到中间后的8张牌=====");
        playingCard = insertCardToMiddle(3, CARDCOUNT);
        System.out.println(playingCard);

        //第五个步骤：把最上面的一张牌藏起来
        kingCard = playingCard.get(0);
        System.out.println("=====被藏起来的第一张牌=====\n"+kingCard);
        playingCard.remove(0);
        CARDCOUNT-=1;
        System.out.println("=====当前剩余的7张卡牌=====\n"+playingCard);

        //第六个步骤：把最上面的1张（南方人）或2张（北方人）或3张（不确定）插到中间
        switch (position) {
            case "Y":
                System.out.println("=====你是南方人,往中间插入一张牌后的7张牌=====");
                playingCard = insertCardToMiddle(1, CARDCOUNT);
                break;
            case "N":
                System.out.println("=====你是北方人,往中间插入两张牌后的7张牌=====");
                playingCard = insertCardToMiddle(2, CARDCOUNT);
                break;
            case "U":
                System.out.println("=====你是中间人,往中间插入三张牌后的7张牌=====");
                playingCard = insertCardToMiddle(3, CARDCOUNT);
                break;
            default:
                System.out.println("没有这个选项");
        }

        System.out.println(playingCard);

        //第七个步骤：扔掉最上面的一张牌（男），或者最上面的两张牌（女）
        switch (gender){
            case "Y":
                System.out.println("=====你是小哥哥,扔掉一张牌后的6张牌=====");
                playingCard.remove(0);
                CARDCOUNT-=1;
                break;
            case "N":
                System.out.println("=====你是小姐姐,扔掉两张牌后的5张牌=====");
                playingCard = playingCard.subList(2,playingCard.size());
                CARDCOUNT-=2;
                break;
        }
        System.out.println(playingCard);

        //第八个步骤:“见证奇迹的时刻”洗牌，每说一个字就把第一张牌放到最下面
        System.out.println("=====见证奇迹的时刻=====");
        playingCard = swapCard(SWAPTITLE.length());
        System.out.println(playingCard);

        //第九个步骤：“好运留下来，烦恼丢出去”，直到留下最后一张
        while(playingCard.size()!=1){
            playingCard = swapCard(1);
            System.out.println("=====好运留下来=====\n"+playingCard);
            playingCard.remove(0);
            CARDCOUNT-=1;
            System.out.println("=====烦恼丢出去=====\n"+playingCard);
        }

        //第十个步骤：判断被藏起来的卡牌和剩余的卡牌是不是同一张卡牌
        if(kingCard.replace("+","").equals(playingCard.get(0).replace("+",""))){
            System.out.println("成功啦！！！");
        }else{
            System.out.println("失败啦！！！");
        }

    }

    /**
     * 将最上面的 n 张卡牌依次切换到最下面
     * @param swapCount 切换的卡牌数量
     * @return
     */
    private static List<String> swapCard(int swapCount){

        //计算实际需要切换的卡牌数量，如果需要切换的数量大于了存在的卡牌数量则切换余数个即可
        //例：现有卡牌数 8 个，需要切换 11 张卡牌，则实际需要切换的只有 11%8=3 张卡牌
        int actualCount = swapCount%playingCard.size();

        //获取需要切换的卡牌数
        List<String> headCard = playingCard.subList(0,actualCount);

        //将切换的牌追加到最后面
        playingCard.addAll(headCard);

        //截取相应数量的卡牌
        return playingCard.subList(actualCount,playingCard.size());
    }


    /**
     * 将前n张卡牌插入到剩余卡牌的中间
     * @param count 需要插入的数量
     * @param remainCount 剩余的数量
     */
    private static List<String> insertCardToMiddle(int count,int remainCount){

        //获取前n张卡牌
        List<String> toInsertCards = playingCard.subList(0,count);
        //把前n张卡牌插入到剩余卡牌的中间
        playingCard.addAll(random.nextInt(remainCount-count-2)+count+1,toInsertCards);
        //此时前n张卡牌依然存在，取右侧的 remainCount 张卡牌即可
        return playingCard.subList(count,playingCard.size());
    }

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        System.out.println("你叫什么名字?");
        String name = scanner.nextLine();

        System.out.println("你是南方小土豆吗[Y/N/U]");
        String position = scanner.nextLine().toUpperCase();

        System.out.println("你是纯爷们吗[Y/N]");
        String gender = scanner.nextLine().toUpperCase();

        decode(name,position,gender);
    }
}